package bigbrother.log;

import bigbrother.ParameterChecker;
import bigbrother.log.daylog.DayLog;
import bigbrother.log.daylog.DayLogId;
import bigbrother.log.daylog.DayLogImpl;
import bigbrother.log.logentries.LogEntry;
import org.apache.jcs.JCS;
import org.apache.jcs.access.exception.CacheException;

import java.io.File;
import java.util.logging.Logger;

/**
 * A {@link Log} implementation that is backed by files containing the logs, and that caches a few of the files in
 * memory, in addition to the one it is currently writing.
 *
 * @author Hans Haggstrom
 */
public final class LogImpl
        implements Log
{

    //======================================================================
    // Private Fields

    private final Logger myLogger = Logger.getLogger( LogImpl.class.getName() );
    private final File myLogStorageDirectory;

    private JCS myCache = null;

    //======================================================================
    // Public Methods

    //----------------------------------------------------------------------
    // Constructors

    /**
     * Creates a new {@link LogImpl}.
     *
     * @param logFileStorageDirectory the directory that log files should be stored under.  Should not be null, and
     *                                should have access rights set so that the irc bot can add new directories and
     *                                files under it.
     */
    public LogImpl( final File logFileStorageDirectory )
    {
        ParameterChecker.checkNotNull( logFileStorageDirectory, "logFileStorageDirectory" );

        myLogStorageDirectory = logFileStorageDirectory;

        setupCache();
    }

    //----------------------------------------------------------------------
    // Log Implementation


    public synchronized DayLog getDay( final DayLogId dayLogId )
    {
        System.out.println( "LogImpl.getDay" );
        DayLog dayLog = null;

        try
        {
            // Get day log from cache
            dayLog = null;
            if ( myCache != null )
            {
                dayLog = (DayLog) myCache.get( dayLogId );
            }


            if ( dayLog == null )
            {
                // Load LogEntry from file system instead, if found (if not found, an empty DayLog will be created).
                dayLog = new DayLogImpl( dayLogId, myLogStorageDirectory );

                addToCache( dayLogId, dayLog );
            }

            System.out.println( "dayLog = " + dayLog );

        }
        catch ( Exception e )
        {
            // DEBUG
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        }

        return dayLog;
    }


    public synchronized void appendEntry( final LogEntry message )
    {
        System.out.println( "LogImpl.appendEntry" );

        final DayLog dayLog = getDay( message.getDayLogId() );

        dayLog.addEntry( message );
    }

    //======================================================================
    // Private Methods

    private void setupCache()
    {
        try
        {
            myCache = JCS.getInstance( "IrcLogCache" );
        }
        catch ( CacheException e )
        {
            myLogger.severe( "Could not initialize logger for IRC logs.  Falling back to direct disk access.  " +
                             e.getMessage() );
        }
    }


    private void addToCache( final DayLogId dayLogId, final DayLog dayLog )
    {
        if ( myCache != null )
        {
            try
            {
                myCache.put( dayLogId, dayLog );
            }
            catch ( CacheException e )
            {
                myLogger.severe( "Problem when adding data to cahce: " + e.getMessage() );
            }
        }
    }

}
